package com.zhou.juc.test06_AtomicXXX;

import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.atomic.LongAdder;

/**
 * @author zhouyanxiang
 * @create 2020-08-2020/8/11-18:47
 */
public class T02_AtomicVsSyncVsLongAdder {

    static Long count1 = 0L;

    static AtomicInteger count2 = new AtomicInteger();

    static LongAdder count3 = new LongAdder();


    public static void main(String[] args) throws InterruptedException {
        Thread[] threads = new Thread[1000];

        for (int i = 0; i < threads.length; i++) {
            threads[i] = new Thread(()-> {
                for (int j = 0; j < 100000; j++) {
                    count2.incrementAndGet();
                }
            });
        }

        Long start = System.currentTimeMillis();

        for (Thread t : threads){
            t.start();
        }

        for (Thread t : threads){
            t.join();
        }

        Long end = System.currentTimeMillis();

        System.out.println( "AtomicInteger  " + count2.get() + " spend time :"  + (end - start));

        System.out.println("================");

        Object lock = new Object();

        for(int i=0; i<threads.length; i++) {
            threads[i] =
                    new Thread(new Runnable() {
                        @Override
                        public void run() {
                            for (int k = 0; k < 100000; k++) {
                                synchronized (lock) {
                                    count1++;
                                }
                            }
                        }
                    });
        }

        start = System.currentTimeMillis();

        for(Thread t : threads ) {
            t.start();
        }

        for (Thread t : threads) {
            t.join();
        }

        end = System.currentTimeMillis();


        System.out.println("Sync: " + count1 + " time " + (end-start));


        System.out.println("================");

        //----------------------------------
        for(int i=0; i<threads.length; i++) {
            threads[i] =
                    new Thread(()-> {
                        for(int k=0; k<100000; k++) {
                            count3.increment();
                        }
                    });
        }

        start = System.currentTimeMillis();

        for(Thread t : threads ) {
            t.start();
        }

        for (Thread t : threads) {
            t.join();
        }

        end = System.currentTimeMillis();

        //TimeUnit.SECONDS.sleep(10);

        System.out.println("LongAdder: " + count1.longValue() + " time " + (end-start));

    }


    static void microSleep(int m) {
        try {
            TimeUnit.MICROSECONDS.sleep(m);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }


}
